#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>

extern "C" JNIEXPORT jstring JNICALL
Java_com_jmd_virus_snaky_OpenCVWrap_imageFilter(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Image filter with opencv";
    return env->NewStringUTF(hello.c_str());
}

extern "C" JNIEXPORT jintArray  JNICALL
Java_com_jmd_virus_snaky_OpenCVWrap_gray(
        JNIEnv* env,
        jobject /* this */,
        jintArray buf, int w, int h) {
    jint *cbuf;
    cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
    if (cbuf == NULL) {
        return 0;
    }

    cv::Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);

    uchar* ptr = imgData.ptr(0);
    for(int i = 0; i < w*h; i ++){
        //计算公式：Y(亮度) = 0.299*R + 0.587*G + 0.114*B
        //对于一个int四字节，其彩色值存储方式为：BGRA
        int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
        ptr[4*i+1] = grayScale;
        ptr[4*i+2] = grayScale;
        ptr[4*i+0] = grayScale;
    }

    int size = w * h;
    jintArray result = env->NewIntArray(size);
    env->SetIntArrayRegion(result, 0, size, cbuf);
    env->ReleaseIntArrayElements(buf, cbuf, 0);
    return result;
}

extern "C" JNIEXPORT jbyteArray  JNICALL
Java_com_jmd_virus_snaky_OpenCVWrap_graybyte(
        JNIEnv* env,
        jobject /* this */,
        jbyteArray buf, int w, int h) {
    jbyte *cbuf;
    cbuf = env->GetByteArrayElements(buf, JNI_FALSE );
    if (cbuf == NULL) {
        return 0;
    }

    cv::Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);

    uchar* ptr = imgData.ptr(0);
    for(int i = 0; i < w*h; i ++){
        //计算公式：Y(亮度) = 0.299*R + 0.587*G + 0.114*B
        //对于一个int四字节，其彩色值存储方式为：BGRA
        int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
        ptr[4*i+1] = grayScale;
        ptr[4*i+2] = grayScale;
        ptr[4*i+0] = grayScale;
    }

    int size = w * h;
    jbyteArray result = env->NewByteArray(size);
    env->SetByteArrayRegion(result, 0, size, cbuf);
    env->ReleaseByteArrayElements(buf, cbuf, 0);
    return result;
}

extern "C" JNIEXPORT jint  JNICALL
Java_com_jmd_virus_snaky_OpenCVWrap_graybuf(
        JNIEnv* env,
        jobject /* this */,
        jbyteArray buf, jbyteArray result, int w, int h) {
    jbyte *cbuf;
    cbuf = env->GetByteArrayElements(buf, JNI_FALSE );
    if (cbuf == NULL) {
        return 0;
    }
    jbyte *out = env->GetByteArrayElements(result, JNI_FALSE);

    cv::Mat myuv(w+h/2, w, CV_8UC1, (uchar *)cbuf);
    cv::Mat mbgr(h, w, CV_8UC3, (uchar *)cbuf);

    cv::cvtColor(myuv, mbgr, CV_YUV420sp2BGR);

    cv::Mat mgray(h, w, CV_8UC1, (uchar*)out);
    cv::cvtColor(mbgr, mgray, cv::COLOR_RGB2GRAY);
    return 0;
}
